﻿using Microsoft.Extensions.DependencyInjection;
using PmSoft.Core.Job.Quartz;
using PmSoft.Core.Job.Timer;
using System.Reflection;
using Quartz;
namespace PmSoft.Core.Job;

/// <summary>
/// 服务集合扩展类，封装作业调度框架的依赖注入
/// </summary>
public static class ServiceCollectionExtensions
{
	/// <summary>
	/// 添加作业调度框架服务
	/// </summary>
	/// <param name="services">服务集合</param>
	/// <param name="assembly">包含作业定义的程序集</param>
	/// <param name="useQuartz">是否使用 Quartz 调度器，false 则使用 Timer</param>
	/// <returns>服务集合</returns>
	public static IServiceCollection AddJobScheduler(this IServiceCollection services, Assembly assembly, bool useQuartz = true)
	{
		// 自动注册所有标记了 JobScheduleAttribute 且实现 IJobDefinition 的类为 Scope 生命周期
		var jobTypes = assembly.GetTypes()
			.Where(t => typeof(IJobDefinition).IsAssignableFrom(t) 
			&& t.IsClass 
			&& !t.IsAbstract 
			&& t.GetCustomAttribute<JobScheduleAttribute>() != null)
			.ToList();

		foreach (var jobType in jobTypes)
		{
			services.AddScoped(jobType);
		}

		// 注册作业类型集合
		services.AddSingleton<IJobTypeCollection>(new JobTypeCollection(jobTypes));

		// 根据配置选择调度器
		if (useQuartz)
		{
			// 配置 Quartz
			services.AddQuartz(q =>
			{
				q.UseDefaultThreadPool(tp => tp.MaxConcurrency = 10); // 配置线程池
			});
			services.AddQuartzHostedService(opt => opt.WaitForJobsToComplete = true); // 托管服务
			services.AddSingleton<IJobSchedulerProvider, QuartzSchedulerProvider>();
		}
		else
		{
			services.AddSingleton<IJobSchedulerProvider, TimerSchedulerProvider>();
		}

		// 注册调度服务
		services.AddHostedService<JobSchedulerService>();

		return services;
	}
}
